package com.xuzao.developer.utils;


import com.xuzao.developer.annotation.ColumnNumberAnnotation;
import com.xuzao.developer.constants.Constants;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 反射工具类
 * @author wangyt
 * @version 1.0 created 2018/8/28
 */
public class ReflectUtils {

    /**
     * 获取一个类的所有属性值（包括父类）
     *
     * @param object       对象
     * @param fieldAmount 列数
     * @return objects
     * @author wangyt created 2018/8/28
     */
    public static Object[] getAllFieldValues(Object object, Integer fieldAmount) {
        //存放属性值list
        Object[] beans = new Object[fieldAmount];
        //获得所有属性
        Field[] fields = ReflectUtils.getAllField(object);
        Arrays.stream(fields).forEach(field -> {
            //允许通过反射访问，
            field.setAccessible(true);
            try {
                //若有该序号注解
                if (field.isAnnotationPresent(ColumnNumberAnnotation.class)) {
                    //获得注解信息
                    ColumnNumberAnnotation annotation = field.getAnnotation(ColumnNumberAnnotation.class);
                    if (Constants.INVALID_SEQUENCENUMBER != annotation.exportOrderNum()) {
                        beans[annotation.exportOrderNum()] = field.get(object);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
        //将列表转为数组放入object数组中
        return beans;
    }

    /**
     * 获取该类所有属性(包括父类)
     *
     * @author wangyt created 2018/8/28
     * @param object 类对象
     * @return objects
     */
    public static Field[] getAllField(Object object) {
        //获取库位视图类的class
        Class clazz = object.getClass();
        //属性列表
        List<Field> fieldList = new ArrayList<>();
        //当class不为空时获得所有(包含父类)属性
        while (clazz != null) {
            fieldList.addAll(new ArrayList<Field>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        //创建属性数组
        Field[] fields = new Field[fieldList.size()];
        //赋值
        fieldList.toArray(fields);
        return fields;
    }

    /**
     * 判断数组是否包含某元素
     *
     * @param arr         数组
     * @param targetValue 对象
     * @return boolean
     * @author wangyt created 2018/8/28
     */
    private static boolean contain(Object[] arr, Object targetValue) {
        for (Object o : arr) {
            if (o.equals(targetValue)) {
                return true;
            }
        }
        return false;
    }
}
